package com.edushare.common.dao;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.Map.Entry;

import com.edushare.common.orm.ORMInterface;
import com.edushare.common.util.StringUtil;
import com.edushare.common.vo.Answers;
import com.edushare.common.vo.Poll;
import com.edushare.common.vo.PollOptions;
import com.edushare.common.vo.PollQuestions;
import com.edushare.common.vo.UserPoll;
import com.edushare.common.vo.Users;

public class UserPollDAO extends CayenneBasedDAO {

	public UserPollDAO(ORMInterface ormInterface) {
		super(ormInterface);
	}

	public int getUserRole(Poll poll, Users user){
		List<UserPoll> pollList = user.getRequestedPolls();
		for(UserPoll p:pollList){
			if(p.getPoll() == poll)
				return p.getUserPollLinkType();
		}
		return 0;
	}

	public void setPollAsDone(Users user, Poll poll) {
		List<UserPoll> upList = user.getRequestedPolls();
		for (UserPoll up : upList) {
			if (up.getPoll() == poll)
				up.setStatus(UserPoll.POLL_COMPLETE);
		}
		getDataContext().commitChanges();
	}

	public boolean isPollDone(Users user, Poll poll) {
		return getPollStatus(user, poll) == UserPoll.POLL_COMPLETE;
	}

	public int getPollStatus(Users user, Poll poll) {
		List<UserPoll> upList = user.getRequestedPolls();
		for (UserPoll up : upList) {
			if (up.getPoll() == poll)
				return up.getStatus();
		}
		return 0;
	}

	public void addUsersToPoll(List<Users> userList, Poll poll, int role) {
		for (Users u : userList) {
			addUserToPoll(u, poll, role);
		}
	}

	public boolean addUserToPoll(Users u, Poll poll, int role) {
		if (getPollStatus(u, poll) != 0)
			return false;
		UserPoll p = new UserPoll();
		p.setPoll(poll);
		p.setUserPollLinkType(role);
		p.setRespondent(u);
		if(role == UserPoll.ROLE_RESPONDENT)
			p.setStatus(UserPoll.POLL_PENDING);
		else
			p.setStatus(UserPoll.POLL_COMPLETE);
		getDataContext().registerNewObject(p);
		getDataContext().commitChanges();
		return true;
	}

	public List<Users> getPollRespondents(Poll poll) {
		List<UserPoll> pollList = poll.getUserPoll();
		List<Users> userList = new ArrayList<Users>();
		for (UserPoll up : pollList) {
			if(up.getUserPollLinkType() != UserPoll.ROLE_REVIEWER)
				userList.add(up.getRespondent());
		}
		return userList;
	}
	
	public List<Users> getPollObservers(Poll poll){
		List<UserPoll> pollList = poll.getUserPoll();
		List<Users> userList = new ArrayList<Users>();
		for (UserPoll up : pollList) {
			if(up.getUserPollLinkType() == UserPoll.ROLE_REVIEWER)
				userList.add(up.getRespondent());
		}
		return userList;		
	}

	public void setAnswer(Users user, PollQuestions pQ, Integer answer) {
		List<Answers> answerList = pQ.getAnswers();
		List<Answers> deleteList = new ArrayList<Answers>();
		for (Answers ans : answerList) {
			if (ans.getUser() == user)
				deleteList.add(ans);
		}
		getDataContext().deleteObjects(deleteList);
		Answers answerVO = new Answers();
		answerVO.setAnswer(answer);
		answerVO.setAnswerDesc("");
		answerVO.setUser(user);
		answerVO.setQuestion(pQ);
		getDataContext().registerNewObject(answerVO);
		getDataContext().commitChanges();
	}

	public void setPreferences(Users user, PollQuestions pQ,
			HashMap<PollOptions, Integer> ansMap) {
		List<Answers> answerList = pQ.getAnswers();
		List<Answers> deleteList = new ArrayList<Answers>();
		for (Answers ans : answerList) {
			if (ans.getUser() == user)
				deleteList.add(ans);
		}
		getDataContext().deleteObjects(deleteList);
		Set<Entry<PollOptions, Integer>> set = ansMap.entrySet();
		for (Entry<PollOptions, Integer> s : set) {
			Answers answerVO = new Answers();
			getDataContext().registerNewObject(answerVO);
			answerVO.setUser(user);
			answerVO.setQuestion(pQ);
			answerVO.setAnswer(s.getKey().getOptionId());
			answerVO.setAnswerDesc(s.getValue().toString());
		}
		getDataContext().commitChanges();
	}

	public Integer getPreference(Users user, PollQuestions pQ, PollOptions po) {
		List<Answers> ansList = pQ.getAnswers();
		for (Answers ans : ansList) {
			if (ans.getUser() == user && ans.getAnswer() == po.getOptionId()) {
				return Integer.valueOf(ans.getAnswerDesc());
			}
		}
		return -1;
	}

	public List<Answers> getAnswerList(Users user, PollQuestions pQ) {
		List<Answers> ansList = pQ.getAnswers();
		List<Answers> retList = new ArrayList<Answers>();
		for (Answers ans : ansList) {
			if (ans.getUser() == user)
				retList.add(ans);
		}
		return retList;
	}

	public List<PollOptions> getAnswer(Users user, PollQuestions pQ) {
		List<Answers> ansList = pQ.getAnswers();
		List<PollOptions> opt = new ArrayList<PollOptions>();
		for (Answers ans : ansList) {
			if (user == ans.getUser() && ans.getAnswer()!= null) {
				opt.add(new PollsDAO(ormInterface).getPollOptionsById(ans
						.getAnswer()));
			}
		}
		return opt;
	}

	public HashMap<String, String> getPreferences(Users user, PollQuestions pQ) {
		List<Answers> ansList = pQ.getAnswers();
		HashMap<String, String> map = new HashMap<String, String>();
		for (Answers ans : ansList) {
			if (user == ans.getUser()) {
				map
						.put(new PollsDAO(ormInterface).getPollOptionsById(
								ans.getAnswer()).getOptionString(), ans
								.getAnswerDesc());
			}
		}
		return map;
	}

	public String getStringAnswer(Users user, PollQuestions pq) {
		List<Answers> ansList = pq.getAnswers();
		for (Answers ans : ansList) {
			if (ans.getUser() == user)
				return ans.getAnswerDesc();
		}
		return "";
	}

	public void setAnswer(Users user, PollQuestions pQ, Integer[] answer) {
		List<Answers> answerList = pQ.getAnswers();
		List<Answers> deleteList = new ArrayList<Answers>();
		for (Answers ans : answerList) {
			if (ans.getUser() == user)
				deleteList.add(ans);
		}
		getDataContext().deleteObjects(deleteList);

		for (Integer i : answer) {
			if (i == null)
				continue;
			Answers answerVO = new Answers();
			answerVO.setAnswer(i);
			answerVO.setAnswerDesc("");
			answerVO.setUser(user);
			answerVO.setQuestion(pQ);
			getDataContext().registerNewObject(answerVO);
		}
		getDataContext().commitChanges();
	}

	public void setAnswer(Users user, PollQuestions pQ, String answer) {
		List<Answers> answerList = pQ.getAnswers();
		List<Answers> deleteList = new ArrayList<Answers>();
		for (Answers ans : answerList) {
			if (ans.getUser() == user)
				deleteList.add(ans);
		}
		getDataContext().deleteObjects(deleteList);

		Answers answerVO = new Answers();
		answerVO.setAnswer(0);
		answerVO.setAnswerDesc(answer);
		answerVO.setUser(user);
		answerVO.setQuestion(pQ);
		getDataContext().registerNewObject(answerVO);
		getDataContext().commitChanges();
	}

	public void clearAnswers(Users user, PollQuestions pQ) {
		List<Answers> answerList = pQ.getAnswers();
		List<Answers> deleteList = new ArrayList<Answers>();
		for (Answers ans : answerList) {
			if (ans.getUser() == user)
				deleteList.add(ans);
		}
		getDataContext().deleteObjects(deleteList);
		getDataContext().commitChanges();
	}

	public Double getAverageRating(PollQuestions pQ) {
		List<Answers> ansList = pQ.getAnswers();
		double rating = 0;
		for (Answers a : ansList) {
			if(isPollDone(a.getUser(), pQ.getPoll()))
				rating += a.getAnswer();
		}
		if (ansList.size() != 0)
			rating = rating / ansList.size();
		return rating;
	}

	public Integer getRating(PollQuestions pQ, Users user) {
		List<Answers> answerList = pQ.getAnswers();
		for (Answers answer : answerList) {
			if (answer.getUser() == user)
				return answer.getAnswer();
		}
		return 0;
	}

	public Integer getTotalResponses(Poll poll) {
		List<UserPoll> upList = poll.getUserPoll();
		Integer resp = 0;
		for (UserPoll up : upList) {
			if (up.getStatus() == UserPoll.POLL_COMPLETE)
				resp++;
		}
		return resp;
	}

	public Integer getResponsesByOption(PollOptions po) {
		List<Answers> answerList = po.getQuestion().getAnswers();
		Integer response = 0;
		for (Answers answer : answerList) {
			if (answer.getAnswer()!= null && answer.getAnswer().equals(po.getOptionId())
					&& isPollDone(answer.getUser(), po.getQuestion().getPoll()))
				response++;
		}
		return response;
	}

	public Integer getMaxOptions(PollQuestions pq) {
		int size = 0;
		List<Answers> ansList = pq.getAnswers();
		for (Answers a : ansList) {
			if (getPollStatus(a.getUser(), pq.getPoll()) == UserPoll.POLL_COMPLETE)
				size++;
		}
		return size;
	}

	public HashMap<Users, String> getFreeFormAnswers(PollQuestions pq) {
		HashMap<Users, String> map = new HashMap<Users, String>();
		List<Answers> ansList = pq.getAnswers();
		for (Answers ans : ansList) {
			map.put(ans.getUser(), ans.getAnswerDesc());
		}
		return map;
	}

	public List<String> getFreeformAnswers(PollQuestions pq) {
		List<String> list = new ArrayList<String>();
		List<Answers> ansList = pq.getAnswers();
		for (Answers ans : ansList) {
			if (StringUtil.isValid(ans.getAnswerDesc()))
				list.add(ans.getAnswerDesc());
		}
		return list;
	}

	public String getUserAnswerReport(Users u, PollQuestions pQ) {
		List<String> s = getUserAnswerReportAsList(u, pQ);
		String str = "";
		if(s!=null && s.size()>0){
			if(s.size()>1){
				for(String r: s){
					str = str + "<p>"+r+"</p>";
				}
			}
			else{
				str=s.get(0);
			}
		}
		return str;
	}
	
	public List<String> getUserAnswerReportAsList(Users u, PollQuestions pQ) {
		List<String> s = new ArrayList<String>();
		switch (pQ.getQuestionType()) {
		case (PollQuestions.QUESTION_TYPE_MULTIPLE_CHOICE):
		case (PollQuestions.QUESTION_TYPE_SINGLE_CHOICE):
		case (PollQuestions.QUESTION_TYPE_DROPDOWN):
			List<PollOptions> pol = this.getAnswer(u, pQ);
			for (PollOptions po : pol) {
				s.add(po.getOptionString());
			}
			return s;
		case PollQuestions.QUESTION_TYPE_PREFERENCES:
			HashMap<String, String> pol1 = this.getPreferences(u, pQ);
			Set<Entry<String, String>> set = pol1.entrySet();
			for (Entry<String, String> e:set) {
				s.add(e.getKey() + ": " + e.getValue());
			}
			return s;
		case (PollQuestions.QUESTION_TYPE_DESCRIBE):
		case (PollQuestions.QUESTION_TYPE_SHORT_TEXT):
				s.add(getStringAnswer(u, pQ));
			return s;
		case (PollQuestions.QUESTION_TYPE_RATING):
			s.add(getRating(pQ, u).toString());
			return s;
		}
		return s;
	}
}
